import hashlib

from django.shortcuts import render, redirect

# Create your views here.

# 跳转到首页
from login.forms import UserForm, RegisterForm
from login.models import User


def index(request):
    pass
    return render(request, 'login/index.html')


"""
登录
    对于非POST方法发送数据时，比如GET方法请求页面，返回空的表单，让用户可以填入数据；
    对于POST方法，接收表单数据，并验证；
    使用表单类自带的is_valid()方法一步完成数据验证工作；
    验证成功后可以从表单对象的cleaned_data数据字典中获取表单的具体值；
    如果验证不通过，则返回一个包含先前数据的表单给前端页面，方便用户修改。也就是说，它会帮你保留先前填写的数据内容，而不是返回一个空表！
    Python内置了一个locals()函数，它返回当前所有的本地变量字典，我们可以偷懒的将这作为render函数的数据字典参数值，
    就不用费劲去构造一个形如{'message':message, 'login_form':login_form}的字典了。这样做的好处当然是大大方便了我们，但是同时也可能往模板传入了一些多余的变量数据，造成数据冗余降低效率。
    """


def login(request):
    # 通过下面的if语句，我们不允许重复登录
    if request.session.get('is_login', None):
        return redirect('/index')

    if request.method == "POST":
        login_form = UserForm(request.POST)
        message = "验证码不正确！"
        if login_form.is_valid():
            username = login_form.cleaned_data['username']
            password = login_form.cleaned_data['password']
            try:
                user = User.objects.get(user_name=username)
                if user is None:
                    message = "用户不存在！"
                # 哈希值和数据库内的值进行比对
                if user.password == hash_code(password):
                    # 通过下面的语句，我们往session字典内写入用户状态和数据, 你完全可以往里面写任何数据，不仅仅限于用户相关！
                    request.session['is_login'] = True
                    request.session['user_id'] = user.id
                    request.session['user_name'] = user.user_name
                    return redirect('/index')
                else:
                    message = "密码不正确！"
            except Exception as e:
                print("异常：", e)
                message = "服务器发生错误！"
        return render(request, 'login/login.html', locals())

    login_form = UserForm()
    return render(request, 'login/login.html', locals())


"""
注册
    从大体逻辑上，也是先实例化一个RegisterForm的对象，然后使用is_valid()验证数据，再从cleaned_data中获取数据。
    重点在于注册逻辑，首先两次输入的密码必须相同，其次不能存在相同用户名和邮箱，最后如果条件都满足，利用ORM的API，创建一个用户实例，然后保存到数据库内。
"""


def register(request):
    if request.session.get('is_login', None):
        # 登录状态不允许注册。你可以修改这条原则！
        return redirect("/index")
    if request.method == "POST":
        register_form = RegisterForm(request.POST)
        message = "验证码不正确！"
        if register_form.is_valid():  # 获取数据
            username = register_form.cleaned_data['username']
            password1 = register_form.cleaned_data['password1']
            password2 = register_form.cleaned_data['password2']
            email = register_form.cleaned_data['email']
            sex = register_form.cleaned_data['sex']
            # 判断两次密码是否相同
            if password1 != password2:
                message = "两次输入的密码不同！"
                return render(request, 'login/register.html', locals())
            else:
                same_name_user = User.objects.filter(user_name=username)
                if same_name_user:  # 用户名唯一
                    message = '用户已经存在，请重新选择用户名！'
                    return render(request, 'login/register.html', locals())
                same_email_user = User.objects.filter(email=email)
                if same_email_user:  # 邮箱地址唯一
                    message = '该邮箱地址已被注册，请使用别的邮箱！'
                    return render(request, 'login/register.html', locals())

                # 当一切都OK的情况下，创建新用户
                new_user = User.objects.create()
                new_user.user_name = username
                new_user.password = hash_code(password1)  # 使用加密密码
                new_user.email = email
                new_user.sex = sex
                new_user.save()
                # 自动跳转到登录页面
                return redirect('/login')
    register_form = RegisterForm()
    return render(request, 'login/register.html', locals())


"""
登出
    flush()方法是比较安全的一种做法，而且一次性将session中的所有内容全部清空，确保不留后患。
    但也有不好的地方，那就是如果你在session中夹带了一点‘私货’，会被一并删除，这一点一定要注意。
"""


def logout(request):
    if not request.session.get('is_login', None):
        # 如果本来就未登录，也就没有登出一说
        return redirect("/index")
    request.session.flush()
    # 或者使用下面的方法
    # del request.session['is_login']
    # del request.session['user_id']
    # del request.session['user_name']
    return redirect("/index")


"""
实现密码加密
使用Python内置的hashlib库，使用哈希值的方式加密密码，可能安全等级不够高，但足够简单，方便使用
"""


def hash_code(s, salt='mysite'):  # 加点盐
    h = hashlib.sha256()
    s += salt
    h.update(s.encode())  # update方法只接收bytes类型
    return h.hexdigest()
